package com.ccjt.efcfs.dto;

import com.ccjt.efcfs.enums.IntervalTypeEnum;
import com.ccjt.efcfs.util.DateUtils;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;

import static com.ccjt.efcfs.constant.CalculateConstant.*;
import static com.ccjt.efcfs.constant.CalculateConstant.Decimal.*;

/**
 * 贷款信息
 */
public class LoanInfo {

    private BigDecimal yearRate; // 年利率
    private BigDecimal monthRate; // 月利率
    private BigDecimal dayRate; // 日利率
    private BigDecimal natureDayRate; // (自然)日利率
    private BigDecimal loanPrincipal; // 贷款本金
    private BigDecimal paidInterest; // 已付利息
    private BigDecimal calRate; // 计算利率(根据分期间隔类型)
    private IntervalTypeEnum intervalType = IntervalTypeEnum.MONTH; // 分期间隔类型(默认为月)
    private BigDecimal intervalQuantity = BD_ONE; // 间隔时间(数量)(默认为1)
    private Date loanDate; // 贷款发生日期
    private Date beginDate; // 首次还款日期
    private Date endDate; // 末次还款日期
    private BigDecimal beginPeriod = BD_ONE; // 起始期数
    private BigDecimal planPeriods; // 计划期数
    private BigDecimal natureYearDays = BD_NATURE_YEAR_DAY; // 指定 (自然)年天数
    private BigDecimal avgPrincipal; // 平均每期本金
    private BigDecimal avgInterest; // 平均每期利息
    private Date earlyRepayDate; // 提前还款日期
    private BigDecimal earlyRepayTotal; // 提前还款总金额
    private BigDecimal earlyRepayServiceCharge; // 提前还款手续费
    private BigDecimal earlyRepayPunishRate; // 提前还款罚息日利率(万五/天)
    private BigDecimal earlyRepayPunishInterest; // 提前还款罚息金额
    private BigDecimal earlyRepayResidualPrincipal; // 提前还款剩余总金额

    /**
     * 构造(年利率, 本金, 总期数, 贷款日期, 首次还款日期, 最后还款日期 ) 分期间隔类型(默认为月)，默认开始期数是 1
     *
     * @param rate
     * @param principal
     * @param periods
     * @param loanDate
     * @param beginDate
     * @param endDate
     */
    public LoanInfo(Double rate, Double principal, Integer periods, String loanDate, String beginDate, String endDate) {
        this(rate, principal, BD_ZERO.doubleValue(), BD_ZERO.intValue(), periods, loanDate, beginDate, endDate);
    }

    /**
     * 构造(年利率, 本金, 起始期数, 总期数, 贷款日期, 首次还款日期, 最后还款日期 ) 分期间隔类型(默认为月)，默认开始期数是1
     *
     * @param rate
     * @param principal
     * @param beginPeriod
     * @param periods
     * @param loanDate
     * @param beginDate
     * @param endDate
     */
    public LoanInfo(Double rate, Double principal, Double interest, Integer beginPeriod, Integer periods, String loanDate, String beginDate, String endDate) {
        this(rate, principal, interest, beginPeriod, periods, loanDate, beginDate, endDate, IntervalTypeEnum.MONTH);
    }

    /**
     * 构造(年利率, 本金, 起始期数, 总期数, 贷款日期, 首次还款日期, 最后还款日期, 分期间隔类型 ) 分期间隔类型(默认为月)，默认开始期数是1
     *
     * @param rate
     * @param principal
     * @param beginPeriod
     * @param periods
     * @param loanDate
     * @param beginDate
     * @param endDate
     * @param periodIntervalType
     */

    public LoanInfo(Double rate, Double principal, Double interest, Integer beginPeriod, Integer periods, String loanDate, String beginDate, String endDate, IntervalTypeEnum periodIntervalType) {
        this.yearRate = new BigDecimal(rate); // 年利率
        this.monthRate = yearRate.divide(new BigDecimal(YEAR_MONTH), CAL_PRECISION, RoundingMode.HALF_UP); // 月利率
        this.dayRate = yearRate.divide(new BigDecimal(FINANCE_YEAR_DAY), CAL_PRECISION, RoundingMode.HALF_UP); // 日利率
        this.natureDayRate = yearRate.divide(natureYearDays, CAL_PRECISION, RoundingMode.HALF_UP); // 日利率
        this.loanPrincipal = new BigDecimal(principal); // 本金
        this.paidInterest = new BigDecimal(interest); // 已付利息
        this.beginPeriod = new BigDecimal(beginPeriod); // 起始期数
        this.planPeriods = new BigDecimal(periods); // 期数

        switch (periodIntervalType) {
            case DAY:
                this.calRate = dayRate;
                break;
            default:
                this.calRate = monthRate;
        }

        this.loanDate = DateUtils.parseDate(loanDate); // 贷款日期
        this.beginDate = DateUtils.parseDate(beginDate); // 首次还款日期
//        this.earlyRepayDate = new Date(); // 如果没有设置提前还款日就按当天算，需要计算利息累积(实时结算营收)
        this.endDate = StringUtils.isNotEmpty(endDate) ? DateUtils.parseDate(endDate) : DateUtils.addMonths(this.beginDate, periods); // 末次还款日期
        this.avgPrincipal = loanPrincipal.divide(planPeriods, CAL_PRECISION, RoundingMode.HALF_UP); // (等本等息)平均每期本金=总金额/总期数
        this.avgInterest = loanPrincipal.multiply(calRate); // (等本等息)平均每期利息=总金额*(分期)计算利率
    }

    public BigDecimal getYearRate() {
        return yearRate;
    }

    public void setYearRate(BigDecimal yearRate) {
        this.yearRate = yearRate;
    }

    public BigDecimal getMonthRate() {
        return monthRate;
    }

    public void setMonthRate(BigDecimal monthRate) {
        this.monthRate = monthRate;
    }

    public BigDecimal getDayRate() {
        return dayRate;
    }

    public void setDayRate(BigDecimal dayRate) {
        this.dayRate = dayRate;
    }

    public BigDecimal getNatureDayRate() {
        return natureDayRate;
    }

    public void setNatureDayRate(BigDecimal natureDayRate) {
        this.natureDayRate = natureDayRate;
    }

    public BigDecimal getLoanPrincipal() {
        return loanPrincipal;
    }

    public void setLoanPrincipal(BigDecimal loanPrincipal) {
        this.loanPrincipal = loanPrincipal;
    }

    public BigDecimal getPaidInterest() {
        return paidInterest;
    }

    public void setPaidInterest(BigDecimal paidInterest) {
        this.paidInterest = paidInterest;
    }

    public BigDecimal getCalRate() {
        return calRate;
    }

    public void setCalRate(BigDecimal calRate) {
        this.calRate = calRate;
    }

    public IntervalTypeEnum getIntervalType() {
        return intervalType;
    }

    public void setIntervalType(IntervalTypeEnum intervalType) {
        this.intervalType = intervalType;
    }

    public BigDecimal getIntervalQuantity() {
        return intervalQuantity;
    }

    public void setIntervalQuantity(BigDecimal intervalQuantity) {
        this.intervalQuantity = intervalQuantity;
    }

    public Date getLoanDate() {
        return loanDate;
    }

    public void setLoanDate(Date loanDate) {
        this.loanDate = loanDate;
    }

    public Date getBeginDate() {
        return beginDate;
    }

    public void setBeginDate(Date beginDate) {
        this.beginDate = beginDate;
    }

    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    public BigDecimal getBeginPeriod() {
        return beginPeriod;
    }

    public void setBeginPeriod(BigDecimal beginPeriod) {
        this.beginPeriod = beginPeriod;
    }

    public BigDecimal getPlanPeriods() {
        return planPeriods;
    }

    public void setPlanPeriods(BigDecimal planPeriods) {
        this.planPeriods = planPeriods;
    }

    public BigDecimal getNatureYearDays() {
        return natureYearDays;
    }

    public void setNatureYearDays(BigDecimal natureYearDays) {
        this.natureYearDays = natureYearDays;
    }

    public BigDecimal getAvgPrincipal() {
        return avgPrincipal;
    }

    public void setAvgPrincipal(BigDecimal avgPrincipal) {
        this.avgPrincipal = avgPrincipal;
    }

    public BigDecimal getAvgInterest() {
        return avgInterest;
    }

    public void setAvgInterest(BigDecimal avgInterest) {
        this.avgInterest = avgInterest;
    }

    public Date getEarlyRepayDate() {
        return earlyRepayDate;
    }

    public void setEarlyRepayDate(Date earlyRepayDate) {
        this.earlyRepayDate = earlyRepayDate;
    }

    public BigDecimal getEarlyRepayTotal() {
        return earlyRepayTotal;
    }

    public void setEarlyRepayTotal(BigDecimal earlyRepayTotal) {
        this.earlyRepayTotal = earlyRepayTotal;
    }

    public BigDecimal getEarlyRepayServiceCharge() {
        return earlyRepayServiceCharge;
    }

    public void setEarlyRepayServiceCharge(BigDecimal earlyRepayServiceCharge) {
        this.earlyRepayServiceCharge = earlyRepayServiceCharge;
    }

    public BigDecimal getEarlyRepayPunishRate() {
        return earlyRepayPunishRate;
    }

    public void setEarlyRepayPunishRate(BigDecimal earlyRepayPunishRate) {
        this.earlyRepayPunishRate = earlyRepayPunishRate;
    }

    public BigDecimal getEarlyRepayPunishInterest() {
        return earlyRepayPunishInterest;
    }

    public void setEarlyRepayPunishInterest(BigDecimal earlyRepayPunishInterest) {
        this.earlyRepayPunishInterest = earlyRepayPunishInterest;
    }

    public BigDecimal getEarlyRepayResidualPrincipal() {
        return earlyRepayResidualPrincipal;
    }

    public void setEarlyRepayResidualPrincipal(BigDecimal earlyRepayResidualPrincipal) {
        this.earlyRepayResidualPrincipal = earlyRepayResidualPrincipal;
    }
}
